//
//  APTagView.swift
//  APSwift
//
//  Created by jianbo.pei on 2022/3/2.
//

import UIKit

public protocol APTagViewDelegate: AnyObject {
    /// 点击tag
    func tagView(_ tagView: APTagView, didTappedTagAt index: Int)
    
    /// 选择的tag数量达到最大值（只有`configuration`的`maxSelectedCount`大于1时有效）
    func tagViewDidReachMaxSelectedCount(_ tagView: APTagView)
}

extension APTagViewDelegate {
    func tagView(_ tagView: APTagView, didTappedTagAt index: Int) {}
    func tagViewDidReachMaxSelectedCount(_ tagView: APTagView) {}
}

open class APTagView: UIView {
    
    public weak var delegate: APTagViewDelegate?
    
    private var internalConfiguration: APTagConfiguration = APTagConfiguration.defaultConfiguration()
    /// tag数据源模型数组
    private var tagModelArray: [APTagModelProtocol]?
    /// 选中的tag模型数组
    private var selectedTagModelArray: [APTagModelProtocol] = []
    /// tag button数组
    private var tagButtonArray: [UIButton] = []
    /// 选中的tag button数组
    private var selectedTagButtonArray: [UIButton] = []
    /// 全选button
    private var allButton: UIButton?
    /// 全选button对应的数据模型
    private var allTagModel: APTagModelProtocol?
    
    open func setup(configuration: APTagConfiguration, tagModels: [APTagModelProtocol]?) {
        guard let tagModels = tagModels else {
            return
        }
        tagModelArray = tagModels
        internalConfiguration = configuration
        for v in subviews {
            v.removeFromSuperview()
        }
        /// 某行当前剩余最大宽度
        var surplusMaxW: CGFloat = configuration.maxTagViewWidth
        /// tag的x
        var tagLeft: CGFloat = 0
        var tagY: CGFloat = 0

        for (index, tagModel) in tagModels.enumerated() {
            if tagModel.tagId() == nil {
                continue
            }
            
            let tagButton = UIButton(type: .custom)
            addSubview(tagButton)
            tagButton.tag = 100 + index
            tagButton.addTarget(self, action: #selector(didTappedTag(sender:)), for: .touchUpInside)
            
            if configuration.tagCornerRadius > 0 {
                tagButton.layer.masksToBounds = true
                tagButton.layer.cornerRadius = configuration.tagCornerRadius
            }
            
            if tagModel.isAll() {
                allButton = tagButton
                allTagModel = tagModel
            }
            
            if tagModel.isSelected {
                tagButton.backgroundColor = configuration.tagSelectedBgColor
                if let attStr = tagModel.tagSelectedAttributedString(), !attStr.string.isEmpty {
                    tagButton.setAttributedTitle(attStr, for: .normal)
                } else if let tagName = tagModel.tagName(), !tagName.isEmpty {
                    tagButton.setTitle(tagName, for: .normal)
                    tagButton.setTitleColor(configuration.tagSelectedTextColor, for: .normal)
                    tagButton.titleLabel?.font = configuration.tagSelectedFont
                } else {
                    tagButton.setTitle("", for: .normal)
                }
                if let tagId = tagModel.tagId(), !tagId.isEmpty {
                    selectedTagButtonArray.append(tagButton)
                    selectedTagModelArray.append(tagModel)
                }
            } else {
                tagButton.backgroundColor = configuration.tagNormalBgColor
                if let attStr = tagModel.tagNormalAttributedString(), !attStr.string.isEmpty {
                    tagButton.setAttributedTitle(attStr, for: .normal)
                } else if let tagName = tagModel.tagName(), !tagName.isEmpty {
                    tagButton.setTitle(tagName, for: .normal)
                    tagButton.setTitleColor(configuration.tagNormalTextColor, for: .normal)
                    tagButton.titleLabel?.font = configuration.tagNormalFont
                } else {
                    tagButton.setTitle("", for: .normal)
                }
            }
            
            var currentTagW: CGFloat = 0
            if let attStr = tagModel.tagNormalAttributedString(), !attStr.string.isEmpty {
                currentTagW = attStr.boundingRect(with: CGSize(width: CGFloat(MAXFLOAT), height: configuration.tagHeight), options: [.usesLineFragmentOrigin], context: nil).size.width + 1.0
            } else if let tagName = tagModel.tagName(), !tagName.isEmpty {
                let tagNameStr = NSString(string: tagName)
                currentTagW = tagNameStr.boundingRect(with: CGSize(width: CGFloat(MAXFLOAT), height: configuration.tagHeight), options: .usesLineFragmentOrigin, attributes: [.font: configuration.tagNormalFont], context: nil).size.width + 1.0
            }
            
            print("currentTagW -- setup - 111 \(currentTagW)")

            currentTagW += (configuration.tagLeftMargin + configuration.tagRightMargin)
            
            if currentTagW >= configuration.maxTagViewWidth {
                currentTagW = configuration.maxTagViewWidth
            }
            
            print("currentTagW -- setup - 222 \(currentTagW)")

            
            if currentTagW <= surplusMaxW {
                /// 当前放的下
                tagButton.frame = CGRect(x: tagLeft, y: tagY, width: currentTagW, height: configuration.tagHeight)
                tagLeft = tagLeft + currentTagW + configuration.horizontalSpacing
                surplusMaxW = surplusMaxW - configuration.horizontalSpacing - currentTagW
            } else {
                /// 当前放不下
                tagY = tagY + configuration.tagHeight + configuration.verticalSpacing
                tagLeft = 0
                surplusMaxW = configuration.maxTagViewWidth
                tagButton.frame = CGRect(x: tagLeft, y: tagY, width: currentTagW, height: configuration.tagHeight)
                tagLeft = currentTagW + configuration.horizontalSpacing
                surplusMaxW = configuration.maxTagViewWidth - currentTagW - configuration.horizontalSpacing
            }
            
            tagButtonArray.append(tagButton)
        }
    }
    
    open class func height(with configuration: APTagConfiguration, tagModels: [APTagModelProtocol]?) -> CGFloat {
        guard let tagModels = tagModels else {
            return 0
        }

        /// 某行当前剩余最大宽度
        var surplusMaxW: CGFloat = configuration.maxTagViewWidth
        /// tag的x
        var tagLeft: CGFloat = 0
        var tagY: CGFloat = 0

        for tagModel in tagModels {
            if tagModel.tagId() == nil {
                continue
            }
            var currentTagW: CGFloat = 0
            if let attStr = tagModel.tagNormalAttributedString(), !attStr.string.isEmpty {
                currentTagW = attStr.boundingRect(with: CGSize(width: CGFloat(MAXFLOAT), height: configuration.tagHeight), options: [.usesLineFragmentOrigin], context: nil).size.width + 1.0
            } else if let tagName = tagModel.tagName(), !tagName.isEmpty {
                let tagNameStr = NSString(string: tagName)
                currentTagW = tagNameStr.boundingRect(with: CGSize(width: CGFloat(MAXFLOAT), height: configuration.tagHeight), options: .usesLineFragmentOrigin, attributes: [.font: configuration.tagNormalFont], context: nil).size.width + 1.0
            }
            print("currentTagW -- height - 111 \(currentTagW)")
            currentTagW += (configuration.tagLeftMargin + configuration.tagRightMargin)
            
            if currentTagW >= configuration.maxTagViewWidth {
                currentTagW = configuration.maxTagViewWidth
            }
            print("currentTagW -- height - 222 \(currentTagW)")

            
            if currentTagW <= surplusMaxW {
                /// 当前放的下
                tagLeft = tagLeft + currentTagW + configuration.horizontalSpacing
                surplusMaxW = surplusMaxW - configuration.horizontalSpacing - currentTagW
            } else {
                /// 当前放不下
                tagY = tagY + configuration.tagHeight + configuration.verticalSpacing
                tagLeft = currentTagW + configuration.horizontalSpacing
                surplusMaxW = configuration.maxTagViewWidth - currentTagW - configuration.horizontalSpacing
            }
        }
        return tagY + configuration.tagHeight
    }
    
    @objc private func didTappedTag(sender: UIButton) {
        guard let tagModelArray = tagModelArray else {
            return
        }
        print("\(sender.tag)")
        let btTag = sender.tag - 100
        
        guard tagModelArray.count > btTag else {
            return
        }
        
        if internalConfiguration.isIgnoreSelected {
            delegate?.tagView(self, didTappedTagAt: btTag)
            return
        }
        
        let tagModel = tagModelArray[btTag]
        
        if tagModel.isAll() {
            /// 如果全选，则后面的都不选中
            for bt in selectedTagButtonArray {
                bt.backgroundColor = internalConfiguration.tagNormalBgColor
                bt.titleLabel?.font = internalConfiguration.tagNormalFont
                bt.setTitleColor(internalConfiguration.tagNormalTextColor, for: .normal)
            }
            selectedTagButtonArray.removeAll()
            selectedTagModelArray.removeAll()
            if tagModel.isSelected {
                /// 取消全选
                tagModel.isSelected = false
            } else {
                /// 全选
                tagModel.isSelected = true
                selectedTagButtonArray.append(sender)
                selectedTagModelArray.append(tagModel)
                sender.backgroundColor = internalConfiguration.tagSelectedBgColor
                sender.titleLabel?.font = internalConfiguration.tagSelectedFont
                sender.setTitleColor(internalConfiguration.tagSelectedTextColor, for: .normal)
                for tagM in tagModelArray {
                    if !tagM.isAll() {
                        tagM.isSelected = false
                    }
                }
            }
        } else {
            if tagModel.isSelected {
                /// 不用考虑全选
                if let index = selectedTagButtonArray.firstIndex(of: sender) {
                    selectedTagButtonArray.remove(at: index)
                }
                
                if let index = selectedTagModelArray.firstIndex(where: {$0.tagId() == tagModel.tagId() && $0.tagId() != nil}) {
                    selectedTagModelArray.remove(at: index)
                }
                
                sender.backgroundColor = internalConfiguration.tagNormalBgColor
                sender.titleLabel?.font = internalConfiguration.tagNormalFont
                sender.setTitleColor(internalConfiguration.tagNormalTextColor, for: .normal)
                tagModel.isSelected = false
            } else {
                if selectedTagModelArray.count >= internalConfiguration.maxSelectedCount, internalConfiguration.maxSelectedCount > 0 {
                    delegate?.tagViewDidReachMaxSelectedCount(self)
                    return
                }
                selectedTagButtonArray.append(sender)
                selectedTagModelArray.append(tagModel)
                tagModel.isSelected = true
                var isAllSelcted = true
                for tagM in tagModelArray {
                    if !tagM.isAll(), !tagM.isSelected {
                        isAllSelcted = false
                        break
                    }
                }
                if isAllSelcted, let allBt = allButton, let allTag = allTagModel {
                    for bt in selectedTagButtonArray {
                        bt.backgroundColor = internalConfiguration.tagNormalBgColor
                        bt.titleLabel?.font = internalConfiguration.tagNormalFont
                        bt.setTitleColor(internalConfiguration.tagNormalTextColor, for: .normal)
                    }
                    selectedTagButtonArray.removeAll()
                    selectedTagModelArray.removeAll()
                    selectedTagButtonArray.append(allBt)
                    selectedTagModelArray.append(allTag)
                    allTag.isSelected = true
                    allBt.backgroundColor = internalConfiguration.tagSelectedBgColor
                    allBt.titleLabel?.font = internalConfiguration.tagSelectedFont
                    allBt.setTitleColor(internalConfiguration.tagSelectedTextColor, for: .normal)
                    for tagM in tagModelArray {
                        if !tagM.isAll() {
                            tagM.isSelected = false
                        }
                    }
                } else if let allBt = allButton, let allTag = allTagModel, allTag.isSelected {
                    allBt.backgroundColor = internalConfiguration.tagNormalBgColor
                    allBt.titleLabel?.font = internalConfiguration.tagNormalFont
                    allBt.setTitleColor(internalConfiguration.tagNormalTextColor, for: .normal)
                    allTag.isSelected = false
                    if let index = selectedTagButtonArray.firstIndex(of: allBt) {
                        selectedTagButtonArray.remove(at: index)
                    }
                    
                    if let index = selectedTagModelArray.firstIndex(where: {$0.tagId() == allTag.tagId() && $0.tagId() != nil}) {
                        selectedTagModelArray.remove(at: index)
                    }
                    sender.backgroundColor = internalConfiguration.tagSelectedBgColor
                    sender.titleLabel?.font = internalConfiguration.tagSelectedFont
                    sender.setTitleColor(internalConfiguration.tagSelectedTextColor, for: .normal)
                } else {
                    sender.backgroundColor = internalConfiguration.tagSelectedBgColor
                    sender.titleLabel?.font = internalConfiguration.tagSelectedFont
                    sender.setTitleColor(internalConfiguration.tagSelectedTextColor, for: .normal)
                }
            }
        }
        delegate?.tagView(self, didTappedTagAt: btTag)
    }
}
